package com.test.chaomai;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Hello {
	@Autowired
	private RedisTemplate<String, Object> redisTemplate;

	@Autowired
	private RedisLockFactory factory;
	
	private static final DefaultRedisScript<Long> STOCK_SCRIPT;
    static {
        // 加载释放锁的脚本
    	STOCK_SCRIPT = new DefaultRedisScript<>();
    	STOCK_SCRIPT.setScriptSource(new ResourceScriptSource(new ClassPathResource("stock.lua")));
    	STOCK_SCRIPT.setResultType(Long.class);
    }

	// 失败尝试，锁导致经常失败，无法卖出
	@GetMapping(value = "/hello")
	public String hello(String name) {

		// 获取锁对象
		RedisLock lock = factory.getReentrantLock("lock1");
		// 尝试获取锁
		boolean isLock = lock.tryLock(1000);

		if (!isLock) {
			// 获取锁失败
			System.err.println("获取锁失败");
			return "error";
		}

		String redisKey = "max";

		Object valueObject = redisTemplate.opsForValue().get(redisKey);
		long value = 0;
		if (valueObject != null) {
			value = Long.parseLong(valueObject.toString());
		}

		try {
			if (value < 50) {
				redisTemplate.opsForValue().increment(redisKey);
				lock.unlock();
			} else {
				System.err.println("已到临界值：" + value);
			}

		} finally {

		}

		return "Hello";
	}

	// 成功尝试
	@GetMapping(value = "/hello1")
	public String hello1(String name) {

		while (true) {
			boolean lock = redisTemplate.opsForValue().setIfAbsent("mylock", 1, 1000, TimeUnit.MILLISECONDS);
			if (!lock) {
				// 获取锁失败
				System.err.println("获取锁失败");
				return "error";
			} else {
				String redisKey = "max";
				Object valueObject = redisTemplate.opsForValue().get(redisKey);
				long value = 0;
				if (valueObject != null) {
					value = Long.parseLong(valueObject.toString());
				}

				if (value < 50) {
					redisTemplate.opsForValue().increment(redisKey);
					redisTemplate.delete("mylock");
				} else {
					System.err.println("已到临界值：" + value);
				}
				break;
			}
		}
		return "Hello";
	}

	// 成功尝试，lua脚本
	@GetMapping(value = "/hello2")
	public String hello2(String name) {
		List<String> keys = new ArrayList<String>();
		keys.add("max");
		
		Long result = redisTemplate.execute(STOCK_SCRIPT,keys);
		if (result == -1) {
			System.out.println("预约失败");
			return "error";
		}

		return "Hello";
	}
}
